package com.jm.call;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.SurfaceView;
import android.widget.Toast;
import com.jm.chat.application.JGApplication;
import org.greenrobot.eventbus.EventBus;

import java.util.Collections;
import java.util.List;
import cn.jiguang.jmrtc.api.JMRtcClient;
import cn.jiguang.jmrtc.api.JMRtcListener;
import cn.jiguang.jmrtc.api.JMRtcSession;
import cn.jiguang.jmrtc.api.JMSignalingMessage;
import cn.jpush.im.android.api.JMessageClient;
import cn.jpush.im.android.api.callback.GetUserInfoCallback;
import cn.jpush.im.android.api.model.UserInfo;
import cn.jpush.im.api.BasicCallback;

/**
 * Created by dyz on 2018/9/20.
 */

public class JMRtcClientManager {
    public static final String CALL_CATEGORY = "call_category";
    public static final String CALL_RECEIVE = "call_receive";
    public static final String CALL_VIDEO = "call_video";
    private String LOG = "Log";
    private static JMRtcClientManager clientManager = new JMRtcClientManager();
    private JMRtcSession session;//通话数据元信息对象
    private static final String[] REQUIRED_PERMISSIONS = new String[]{Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA};
    private boolean requestPermissionSended = false;
    private static Activity mActivity;
    private JMRctCallback jmRctCallback;

    public static JMRtcClientManager getJMRtcClientManager(){
        return clientManager;
    }

    public void initEngine(Activity activity){
        mActivity = activity;
        JMRtcClient.getInstance().initEngine(jmRtcListener);
    }
    public void setJMRctCallback(JMRctCallback jmRctCallback){
        this.jmRctCallback = jmRctCallback;
    }

    public void onResume() {
        if (requestPermissionSended) {
            if (AndroidUtils.checkPermission(JGApplication.context, REQUIRED_PERMISSIONS)) {
                JMRtcClient.getInstance().reinitEngine();
            } else {
                Toast.makeText(JGApplication.context, "缺少必要权限，音视频引擎初始化失败，请在设置中打开对应权限", Toast.LENGTH_LONG).show();
            }
        }
        requestPermissionSended = false;
    }

    /**
     * 发起语音通话
     * @param username
     * @param mediaType
     * JMSignalingMessage.MediaType.AUDIO
     */
    public void startCall(String username, final JMSignalingMessage.MediaType mediaType) {
        JMessageClient.getUserInfo(username, new GetUserInfoCallback() {
            @Override
            public void gotResult(int responseCode, String responseMessage, UserInfo info) {
                Log.e(LOG, "get user info complete. code = " + responseCode + " msg = " + responseMessage);
                if (null != info) {
                    JMRtcClient.getInstance().call(Collections.singletonList(info), mediaType, new BasicCallback() {
                        @Override
                        public void gotResult(int responseCode, String responseMessage) {
                            String text = responseCode==0?"发起通话成功,等待对方响应":"发起失败";
                            Log.e(LOG, text + " call send complete . code = " + responseCode + " msg = " + responseMessage);
                            EventBus.getDefault().postSticky(new CallEventBean(CallEventBean.EVENT_START_CALL,responseCode));
                        }
                    });
                } else {
                    EventBus.getDefault().postSticky(new CallEventBean(CallEventBean.EVENT_START_CALL,-1));
                }
            }
        });
    }

    /**
     * 接听
     */
    public void acceptCall() {
        JMRtcClient.getInstance().accept(new BasicCallback() {
            @Override
            public void gotResult(int responseCode, String responseMessage) {
                String text = responseCode==0?"接听电话成功":"接听失败";
                Log.e(LOG, text + " accept call!. code = " + responseCode + " msg = " + responseMessage);
                EventBus.getDefault().postSticky(new CallEventBean(CallEventBean.EVENT_ACCEPT_CALL_SUCCESS,responseCode));
            }
        });
    }
    /**
     * 拒听
     */
    public void refuseCall() {
        JMRtcClient.getInstance().refuse(new BasicCallback() {
            @Override
            public void gotResult(int responseCode, String responseMessage) {
                String text = responseCode==0?"拒听电话成功":"拒听失败";
                Log.e(LOG, text + " refuse call!. code = " + responseCode + " msg = " + responseMessage);
                EventBus.getDefault().postSticky(new CallEventBean(CallEventBean.EVENT_REFUSE_CALL_SUCCESS,responseCode));
            }
        });
    }

    /**
     * 挂断
     */
    public void hangUp() {
        JMRtcClient.getInstance().hangup(new BasicCallback() {
            @Override
            public void gotResult(int responseCode, String responseMessage) {
                String text = responseCode==0?"挂断成功":"挂断失败";
                Log.e(LOG, text +  "hangup call!. code = " + responseCode + " msg = " + responseMessage);
                EventBus.getDefault().postSticky(new CallEventBean(CallEventBean.EVENT_HANGUP_CALL_SUCCESS,responseCode));
            }
        });
    }

    JMRtcListener jmRtcListener = new JMRtcListener() {
        @Override
        public void onEngineInitComplete(final int errCode, final String errDesc) {
            super.onEngineInitComplete(errCode, errDesc);
            Log.e(LOG,"音视频引擎初始化完成。 errCode = " + errCode + " err Desc = " + errDesc);
            EventBus.getDefault().postSticky(new CallEventBean(CallEventBean.EVENT_ENGINE_INIT_COMPLETE,errCode));
        }

        @Override
        public void onCallOutgoing(JMRtcSession callSession) {
            super.onCallOutgoing(callSession);
            Log.e(LOG, "onCallOutgoing invoked!. session = " + callSession.toString()+";;通话已播出");
//            EventBus.getDefault().postSticky(new CallEventBean(CallEventBean.EVENT_ON_CALL_OUTGOING,-1));
            session = callSession;
        }

        @Override
        public void onCallInviteReceived(JMRtcSession callSession) {
            super.onCallInviteReceived(callSession);
            Log.e(LOG, "onCallInviteReceived invoked!. session = " + callSession.toString()+";;收到通话邀请");
            Intent intent = new Intent(JGApplication.context,CallActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.putExtra(CALL_CATEGORY,CALL_RECEIVE);
            String type = JMSignalingMessage.MediaType.VIDEO == callSession.getMediaType()?"video":"";
            intent.putExtra(CALL_VIDEO,type);
            JGApplication.context.startActivity(intent);
//            EventBus.getDefault().postSticky(new CallEventBean(CallEventBean.EVENT_ON_CALL_INVITE_RECEIVED,-1));
            session = callSession;
        }

        @Override
        public void onCallOtherUserInvited(UserInfo fromUserInfo, List<UserInfo> invitedUserInfos, JMRtcSession callSession) {
            super.onCallOtherUserInvited(fromUserInfo, invitedUserInfos, callSession);
            Log.e(LOG, "通话中有其他人被邀请 onCallOtherUserInvited invoked!. session = " + callSession.toString() + " from user = " + fromUserInfo
                    + " invited user = " + invitedUserInfos);
            session = callSession;
        }

        //主线程回调
        @Override
        public void onCallConnected(JMRtcSession callSession, SurfaceView localSurfaceView) {
            super.onCallConnected(callSession, localSurfaceView);
            Log.e(LOG, "通话连接已建立 onCallConnected invoked!. session = " + callSession.toString() + " localSerfaceView = " + localSurfaceView);
            EventBus.getDefault().postSticky(new CallEventBean(CallEventBean.EVENT_ON_CALL_CONNECTED,-1));
            session = callSession;
            if(jmRctCallback!=null){
                jmRctCallback.onCallConnected(callSession,localSurfaceView);
            }
        }

        //主线程回调
        @Override
        public void onCallMemberJoin(UserInfo joinedUserInfo, SurfaceView remoteSurfaceView) {
            super.onCallMemberJoin(joinedUserInfo, remoteSurfaceView);
            Log.e(LOG, "有其他人加入通话 onCallMemberJoin invoked!. joined user  = " + joinedUserInfo + " remoteSerfaceView = " + remoteSurfaceView);
            if(jmRctCallback!=null){
                jmRctCallback.onCallMemberJoin(joinedUserInfo,remoteSurfaceView);
            }
        }

        @Override
        public void onPermissionNotGranted(final String[] requiredPermissions) {
            Log.e(LOG,"[onPermissionNotGranted] permission = " + requiredPermissions.length);
            try {
                AndroidUtils.requestPermission(mActivity, requiredPermissions);
                requestPermissionSended = true;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onCallMemberOffline(final UserInfo leavedUserInfo, JMRtcClient.DisconnectReason reason) {
            super.onCallMemberOffline(leavedUserInfo, reason);
            Log.e(LOG, "有人退出通话 onCallMemberOffline invoked!. leave user = " + leavedUserInfo + " reason = " + reason);
            EventBus.getDefault().postSticky(new CallEventBean(CallEventBean.EVENT_ON_CALL_ERROR,-1));
        }

        @Override
        public void onCallDisconnected(JMRtcClient.DisconnectReason reason) {
            super.onCallDisconnected(reason);
            Log.e(LOG, "本地通话连接断开 onCallDisconnected invoked!. reason = " + reason);
            int responseCode = -1;
            if(JMRtcClient.DisconnectReason.hangup==reason){
                responseCode = 1;
            }
            EventBus.getDefault().postSticky(new CallEventBean(CallEventBean.EVENT_ON_CALL_ERROR,responseCode));
            session = null;
        }

        @Override
        public void onCallError(int errorCode, String desc) {
            super.onCallError(errorCode, desc);
            Log.e(LOG, "通话发生错误 onCallError invoked!. errCode = " + errorCode + " desc = " + desc);
            //872002通话超时
            EventBus.getDefault().postSticky(new CallEventBean(CallEventBean.EVENT_ON_CALL_ERROR,errorCode));
            session = null;
        }

        @Override
        public void onRemoteVideoMuted(UserInfo remoteUser, boolean isMuted) {
            super.onRemoteVideoMuted(remoteUser, isMuted);
            Log.e(LOG,"onRemoteVideoMuted invoked!. remote user = " + remoteUser + " isMuted = " + isMuted);

        }
    };

    public interface JMRctCallback{
        void onCallConnected(JMRtcSession callSession, SurfaceView localSurfaceView);
        void onCallMemberJoin(UserInfo joinedUserInfo, SurfaceView remoteSurfaceView);
    }
}
